<?php


namespace app\api\service;


use app\lib\enum\OrderStatusEnum;
use app\lib\exception\orderException;
use app\lib\exception\TokenException;
use think\Loader;
use think\Log;
use app\api\model\Order as orderModel;

//EXTEND_PATH 表示extend目录的路径
// extend/WxPay/WxPay.Api.php
Loader::import('WxPay.WxPay',EXTEND_PATH,'.Api.php');


class Pay{
    private $order_id;
    private $order_no;

    public function __construct($orderid){
        if(!$orderid){
            throw new orderException(['msg'=>'订单号不能为空']);
        }
        $this->order_id = $orderid;
    }

    public function pay(){
        /**
         * 订单号可能根本就不存在，
         * 订单号确实存在，但是订单号和当前用户是不匹配的
         * 订单可能已被支付过了
         */
        //进行库存量的检测
        $this->checkOrderVaild();
        $orderService = new Order();
        $status = $orderService->checkOrderStock($this->order_id);
        if(!$status['pass']){
            return $status;
        }

        return $this->makeWxpreOrder($status['orderPrice']);


    }

    //订单id,用户uid,是否已支付的检测
    private function checkOrderVaild(){
        //检测订单是否存在
        $orderModel = new \app\api\model\Order();
        $order = $orderModel::where('id','=',$this->order_id)->find();
        if(!$order){
            throw new orderException(['msg'=>'订单不存在']);
        }

        //检测当前用户是否和缓存中的是统一用户
        if(!Token::isValidOperate($order->user_id)){
            throw new TokenException(['msg'=>'注意不是本人在操作']);
        }

        //检测订单是否被支付
        if($order->status !=OrderStatusEnum::UNPAID){
            throw new orderException(['msg'=>'订单 已支付']);
        }

        $this->order_no = $order->order_no;
        return true;
    }


    //微信预订单的生成
    private function makeWxpreOrder($totalPrice){
        $openid = Token::getCurrentToken('openid');
        if(!$openid){
            throw new TokenException();
        }

        //调用统一下单
        $wxOrderData = new \WxPayUnifiedOrder();
        $wxOrderData->SetOut_trade_no($this->order_no);
        $wxOrderData->SetTrade_type('JSAPI');
        $wxOrderData->SetTotal_fee($totalPrice *100);
        $wxOrderData->SetBody('零食商贩');
        $wxOrderData->SetOpenid($openid);
        $wxOrderData->SetNotify_url(config('secure.pay_back_url'));

        //调用
        return  $this->getPaySignature($wxOrderData);

    }


    private function getPaySignature($wxOrderData){
        $wxOrder = \WxPayApi::unifiedOrder($wxOrderData);
        var_dump($wxOrder);

        if($wxOrder['return_code'] !='SUCCESS' || $wxOrder['result_code'] !='SUCCESS'){
            Log::record($wxOrder,'error');
            Log::record('获取预支付订单失败','error');
        }
        //prepay_id 向用户推送消息需要用到，保存到该条订单数据中
        $this->recodePrePayId($wxOrder['prepay_id']);
        //将数据返回到客户端
        $signData = $this->sign($wxOrder);
        return $signData;
    }


    //保存prepay_id导数据库
    private function recodePrePayId($prepayid){
        $res = orderModel::where('id',$this->order_id)->update(['prepay_id'=>$prepayid]);
        if(!$res){
            throw new orderException(['msg'=>'更新prepay_id失败']);
        }
        return true;
    }

    //生成返回数据，将该数据返回到客户端
    private function sign($wxOrder){
        $jsApiPayData = new \WxPayJsApiPay();
        //小程序的appid
        $jsApiPayData->SetAppid(config('wx.appId'));
        //时间戳,字符串类型
        $jsApiPayData->SetTimeStamp((string)time());
        //随机字符串
        $nonceStr = md5(time().mt_rand(0,1000));
        $jsApiPayData->SetNonceStr($nonceStr);
        //数据包
        $jsApiPayData->SetPackage('prepay_id='.$wxOrder['prepay_id']);
        //签名算法
        $jsApiPayData->SetSignType('MD5');
        //签名,WxPayJsApiPay() 内置的MakeSign()方法生成签名
        $sign = $jsApiPayData->MakeSign();
        //返回原生参数，不包含签名
        $rawValues = $jsApiPayData->GetValues();
        $rawValues['paySign'] = $sign;
        //这个数组中包含了appid，但是该数据是不需要返回到的
        unset($rawValues['appId']);
        return $rawValues;

    }

}



